freecivfandomcom-20200223-history
Pubserver software
=General description= This document describes the software used to drive pubserver, the public set of Freeciv servers kept running at pubserver.freeciv.org. This document is supposed to reflect as closely as possible the actual situation, and concerns only the original system of pubserver software developed mostly by Reinier Post and Paul Zastoupil. Specifically, it does not describe publite and other initiatives to replace parts of this system with something else, since they are not ready to take over production just yet. Please do not use this document to describe wishes or plans regarding the pubserver software or discuss its design; the Pubserver Internals document exists for that purpose. See also pubserver system administration. Purpose of the pubserver software The specific purpose of pubserver is to provide a public Freeciv service: it runs a battery of Freeciv servers that users can connect to from all over the Internet with their Freeciv clients to play Freeciv games. All this is installed under the freeciv account's home directory. The software and website are under CVS control, with its repository on cvs.freeciv.org; it has not been made publically available. Portability The software is quite portable; the build system used to be cross-tested on a Solaris host (svis02.win.tue.nl, to be exact). It may be an idea to start crosstesting it on Cygwin, this shouldn't pose much of a problem. One file, share/Makefile, depends on GNU make. Some of the auxiliary tools outside the build system (i.e. not called by civservers) are Linux specific (e.g. depend on the Linux /proc filesystem). Filesystem layout One way to look at the software is to see where it lives on the file system. Everything is owned by the freeciv user and can be found under ~freeciv (some things are symlinked there from somewhere else). (Note that it would be safer to have separate users for separate parts.) The relevant directory trees are: ;~freeciv/bin: command line utilities for maintenance and monitoring, the build system, and post-game reporting (mostly scripts in bin/sh and Perl) ;~freeciv/share: auxiliaries for these executables (e.g. an important Makefile) ;~freeciv/.freeciv/code: Freeciv civserver executables with supporting data, at various stages of compilation and installation (the process is controlled from share/Makefile) ;~freeciv/.freeciv/games: the working directories of all running games ~freeciv/.freeciv/* config files, abuse reports, etcetera ;~freeciv/htdocs/games: the game reports on completed games ;~freeciv/htdocs/*: the rest of the website, with dynamic pages using PHP This does not completely organize everything by its function; it really should. For example, all the different kinds of command line utilities live together in ~freeciv/bin, together with a couple of throwaway and dysfunctional scripts, which is quite inconvenient. Post-game data are kept partly as files on disk, partly in a MySQL database on www.freeciv.org. =The software, organized by function= Overview In all, the pubserver software consists of over 40 scripts; they will now be described organized by their function within the whole. The pubserver software can be split according to funtion, as follows: ; the build system: a system of command line tools that assembles and runs a battery of Freeciv servers ; post-game reporting: a system of command line tools that archives game results and creates (not so) pretty reports for them ; cleanup: command line tools to erase working directories that are no longer needed ; monitoring: additional command line tools for the pubserver admin to see what is going on ; website: displays the pubserver status and the post-game reports to end users __TOC__ The build system The software to operate the Freeciv servers consists of a couple of scripts that call each other. Here is most of the call graph, showing only calls to homemade utility scripts - calls to external utilities (make, GET, patch, gnuplot, gifsicle, etc. etc.) are not included. bin/civservers | +-+> share/Makefile | +-+> fetch | +-+> patch | | | +-+> bin/cvsdiff2udiff | | | +-+> bin/p0p1 | +-+> config | +-+> compile | +-+> diff-patch, diff-compile | +-+> install | +-+> start, restart | | | +-+> bin/civserver-forever | | | | . +-+> bin/cs | . | | . +-+> bin/newsubdir | | | +-+> .freeciv/code/(...)/civserver | +-+> stop | | | +-+> bin/civserver-kill | +-+> wipe-fetch, wipe-patch, wipe-compile, wipe-install | +-+> fetched-in, patched-in, compiled-in, installed-in . . +-+> picture-civgame | +-+> -d (database update) | | | +-+> bin/serversettings | | | +-+gt; bin/doranking | | | +-+gt; /home/hirisov/script/doranking, /home/hirisov/script/tourny | | | +-+gt; bin/xmlgamelogparse | +-+> -a (analyse core dump) | | | +-+> bin/civserver-core-backtrace | +-+> -c (copy game data) | +-+> -r (generate animated replay map) | | | +-+> bin/sortsav | | | +-+> bin/ppm2gif | | | +-+> bin/fcivppsav | | | +-+> bin/fcivppint | | | +-+> bin/fcivmaprace | | | +-+> bin/fcivmapplayers | +-+> -p (generate score plots) | +-+> bin/savs2time | +-+> bin/civscore2gnuplot | +-+> bin/colorize-gnumultiplot-ps Top-down: bin/civservers The purpose of this script is twofold: * it stores the pubserver configuration details, listing which server configuration runs on which port * it acts as the general control shell It may not seem logical to let a script be its own configuration file, but it keeps things in one place and provides the flexibility required. Since civservers is its own configuration file, it contains a minimal amount of code: all actual functionality is delegated to share/Makefile. The script can be called without arguments to perform whatever is required to get everything going, or with specific arguments to perform specific subfunctions. The calling syntax is /etc/init.d idiom (civservers start, etc.) extended to support all the various subfunctions (civservers patch, civservers install, etc.). Subfunctions depend on each other (e.g. you can't compile without having applied the indicated patches, you can't apply patches without having fetched the indicated code base). This is why civservers is just a wrapper around share/Makefile and its arguments are the Makefile targets. There are special targets of the form wipe-* to forcibly remove the results of a particular step; e.g. wipe-patch erases the results of patch, so re-patching can be forced. There are two ways of making this script display its actions without executing them: * civservers -n action will display the make command that would be invoked, without actually doing so * civservers -n will execute the make command with the -n option, causing make to display its actions without executing them Sorely missing is an option to execute civservers on just a specific port or range of ports; however, the -n option can be used to get around this. Called by cron, but often used on the command line. It is important to be aware that this script runs automatically from cron. Certain configurations that are easy to choose by mistake (e.g. telling it to recompile from current CVS on every run) will make the host spin out of resources. share/Makefile Automatically creates and deploys a civserver from specifications given als command line options and/or environment variables. The following stages are distinguished: ;fetch: fetches source code from a tarball on the web or from CVS ;patches: fetches a list of patches from rt.freeciv.org ;patch: patches the source code with the list of patches (if any) (presently found in ~freeciv/patches, should be obtained from RT) ;compile: configures and compiles the resulting source code tree ;install: installs the compiled tree into a different directory ;start: deploys an installed server on one or more TCP ports Each stage except the last stores its results in a different subdirectory of ~freeciv/code. The last stage calls bin/civserver-forever to do the real work. Although many functions are performed by command line tools in bin/*, a quite large amount of code has been build up directly within this Makefile, which makes it quite hard to read and maintain. The individual steps (targets) should be delegated to scripts. bin/cvsdiff2udiff Modifies patches (mainly those from CVS) to a unified diff format. Called by civservers patch, but useful on its own. bin/p0p1 Looks at a Freeciv patch to determine whether to patch it with -p0 or -p1. Called by civservers patch, but useful on its own. bin/civserver-forever Keeps a civserver running in an endless loop, by restarting it when it quits. Server output is saved to civserver.out, which is important in investigating abuse reports. The present version uses civserver's -quitidle flag to make the server quits when no users are present. (Earlier versions depended on parsing the server output to determine this condition and sending a /quit response on input when it was met.) The present version also initiates post-game reporting, which can alternatively be started independently from cron. Called by civservers start and civservers restart, but useful on its own. bin/cs Starts a civserver in a newly created subdirectory under ~freeciv/.freeciv/games. This guarantees that two different civservers do not overwrite each other's output data, such as savegames and game logs. The directory name is a counter; many scripts use it to identify the game, e.g. on the website. Called by bin/civserver-forever, but useful on its own. bin/newsubdir An auxiliary script to create a new subdirectory. Called by bin/cs, but useful on its own. bin/civserver-kill Kills the civserver process(es) running on the port(s) supplied on the command line. Called by civservers stop, but useful on its own. Post-game archiving and reporting Another set of scripts has the purpose of condensing the data dumped on disk by an ended civserver to a manageable quantity and generating Web-accessible overviews. bin/picture-civgames This script can be called to do post-game processing on existing game directories. It simply calls bin/picture-civgame on the specified game directories. Designed to be called by cron, but useful on its own. bin/picture-civgame This script performs all post-game processing on a game. It serves four purposes: * running reporting software on the game data to display (not so) pretty statistics and graphs to end users * condensing and archiving all relevant game data into a subdirectory on the webserver, so the original working directory can be cleaned out; * recording game results into the game database (including a computation of ranking information) * alerting Freeciv admins in case of problems As you can tell from its name, the script started out doing only the first part; it created an animated replay map and some gnuplot gaphs and saved them to a directory on the website for viewing with htdocs/viewgame.phtml. Later, the information saved to that directory was extended in two ways: * game information was added that doesn't show up to end users (e.g. the civserver output, to investigate abuse, and a coredump, if the server crashed) * intermediate information was added so the graphing can be re-run (so we can improve the graphing part and rerun it on old games) Furthermore, game information was saved to a MySQL database; we now depend on it for authentication and ranking. Two different ranking systems are invoked, in fact. Finally, when the server is found to have crashed, a core dump backtrace is emailed to the Freeciv admins. Like bin/civservers, the script can be called without arguments, in which case it will do everything, or with arguments, to execute a particular subfunction. Care was taken to make all execution re-entrant: the script and its subfunctions can be rerun without leading to invalid results. The exception is the database update and ranking computation, for which I (rp) don't know how to make them reentrant; see the descripton of bin/doranking for details. Takes care not to execute on games that are still running: the results would generally be invalid and should not yet be available anyway. By default, will skip subfunctions that have been executed before; does not employ a Makefile to implement this. Re-execution can be forced with the -f option. Called by bin/picture-civgames and bin/civserver-forever, but useful on its own. bin/serversettings Inserts game results into the game database. Called by bin/picture-civgame. Ought to be reentrant. bin/doranking Computes player ranking updates based on the game results, and inserts them into the game database. Called by bin/picture-civgame. Ought to be reentrant. /home/hirisov/script/doranking, /home/hirisov/script/tourny An improved ranking system designed and implemented by hirisov. Called by bin/picture-civgame. Ought to be reentrant; since ranking depends not only on the present game's results, but also on the participants' rankings at the time the ranking is updated, this is not so easy to achieve. Ideally, the update should be history independent, and e.g. record a timestamp to indicate the moment of update; that way, both the update and the ranking computation become reentrant. bin/xmlgamelogparse Called by bin/picture-civgame, but useful on its own. Converts a 2.1 format gamelog to the old format, I believe. bin/civserver-core-backtrace Runs gdb to create a backtrace of a civserver coredump (if present). Called by bin/picture-civgame, but useful on its own. bin/sortsav Called by bin/picture-civgame, but useful on its own. bin/ppm2gif Not a homegrown script, but a standard unitity to convert images from PPM to GIF format. Called by bin/picture-civgame. bin/fcivppsav, bin/fcivppint, bin/fcivmaprace, bin/fcivmapplayers Perl scripts that extract useful information from the series of savegames left by a game. Based on common code in share/perl. Called by bin/picture-civgame. There is a performance bottleneck here. bin/savs2time From a series of Freeciv savegames and their mtimes, computes actual time consumption and timeout information, and saves it in Freeciv scorelog format. Called by bin/picture-civgame, but useful on its own. bin/civscore2gnuplot Takes information in Freeciv scorelog format and graphs it with gnuplot, to produce the game graphs shown in htdocs/viewgame.phtml. Called by bin/picture-civgame, but useful on its own. bin/colorize-gnumultiplot-ps Recolories gnuplot graphs produced by bin/civsciore2gnuplot, since games may feature more players than the number of different colors gnuplot can emit. Called by bin/picture-civgame. ~freeciv/share Contains auxiliary files (mostly code) that aren't executable scripts: ;share/Makefile: the heart of the autobuilding system for civservers ;share/perl: a Perl library to parse with Freeciv game data The Makefile is discussed elsewhere. share/perl A simple Perl library, written by Todd Goodman, is available for parsing Freeciv savegames: Freeciv::SavFiles. It is used in utility scripts called by picture-civgame. Cleanup commands Some are automatically invoked by cron. bin/cleanup-gamedata Removes working directories of Freeciv servers that are no longer running. Arguments specify criteria for removal. Called from cron, but mostly useful on the command line (cron is careful not to remove too much). bin/cleanup-unused-code Removes the directory trees under ~freeciv/.freeciv/code that are no longer used by the present bin/civservers configuration. Determining this is a little tricky, which is why it is not called from cron. bin/civgame-clean Reduces the number of savegames in a server's working directory, as if civserver had been invoked with the saveturns parameter supplied as argument. Not used. Monitoring commands Some utilities support the pubserver admin logging on to pubserver to see what is going on: bin/civserver-port-pid-dir The primary way to survey what is running on pubserver. For each running server, lists its pubserver port, process id, and working directory. Within the working directory, files are to be found that show the civserver version and startup configuration. It is important to note that the set of running servers typically does not correspond to the set configured in bin/civservers. A different configuration will only take effect on a port after the running civserver has been terminated, which will only happen when no more users are connected to it. bin/civserver-connections Lists the running civservers with their port and the hostnames of the connected users. bin/civserver-ping Pings users connected to a given pubserver port. Useful in determining connectivity problems. This was important in the pre-1.12.0 days, when poor connectivity from one user would routinely lock up the server for everbody else. Not much used today. bin/civserver-status Another way to list the status of running civservers. bin/civserver-quit Issues a /quit command to a running civserver. No longer works, because civserver-forever no longer supports supplying server command line input to the civservers it starts. (A pretty useful feature that was removed for unknown reasons.) bin/freecivs An old client side script. Lists the Freeciv servers shown on the Freeciv metaserver and optionally invokes a Freeciv clients to connect to them. Not used. Not updated to support the 2.x metaserver. bin/free-ports-between Finds ports on which no server is running. Called by share/Makefile, but useful on its own. bin/proc-net-tcp2host-port Roughly, a non-civserver-specific version of bin/civserver-port-pid-dir. bin/diskspace-check Estimates whether enough disk space is available for running games. Called by cron, but useful on its own. bin/* Scripts for which a description is still missing: civcities civparse civpath2server civpow civyears2turns cpfreeciv doallranking fix-civscore forxcpu gamelog2html getnumbers impatiently mkpatch names nrframes onlyone report-civscore sav2ppm sav2score save4patch savplayers savyear tar.gz-civserver testcolorcube testxcpu The pubserver website: ~freeciv/htdocs The pubserver website displays information on past and present pubserver games. It combined preprocessed information with information from the games database and on-the-fly formatting, using PHP as the scripting language. The main pages on the webserver are ;index.phtml: The main page; contains a table with news items that requires updating after user-visible changes. ;viewgame.phtml: Reports on an individual game. Most reporting data, such as the animated replay map and the game statistics histograms, are pregenerated, but this script is still quite slow. Some optimizatiuon has been done, e.g. in the generation of URLs for the previous and next buttons, but more is required. ;query.phtml: Displays a table of games from the (MySQL) database. Supports sorting and selecting by specific columns, and crosslinks with viewgame.phtml, but the interface is quite primitive; more features and columns could be added, and the interface could probably be made easier to use. ;rankings.phtml: Displays a table of players from the database, by ranking. The ranking system, designed by Paul Zastoupil and Micha Riser, has known strengths and weaknesses. Other webpages: a gamelog prettyprinter (contributed by Sönke Ufen), a directory of IRC users, a (cyphor) message board, and more. The data directories An overview of the data on the filesystem employed by the pubserver software. FAR FROM COMPLETE. ~freeciv/code pubserver.freeciv.org always runs multiple Freeciv versions and always applies various special patches to the source code. In January, 2003, for example, the following versions were running: ;1.13.0: because Linux distributions were packaging it ;1.14.0-beta2: with the "teams" patch (a popular feature) ;1.14.0: the latest stable release, against which the "teams" patch would not work ;current CVS: always available for playtesting, updated automatically All have extra patches applied to fix bugs and add special behaviour. For instance, abuse in the past has led to a very simple patch that sets the minimum timeout to 40. Another patch adds a server command to add observer players to the game. A civserver binary requires a matching data directory for rulesets, nations, etcetera. Therefore, every different variant is installed (with make install into a separate directory tree, and started from there. These trees are under ~freeciv/.freeciv/code/installed. The other subdirectories of ~freeciv/.freeciv/code are working directories used during the compilation process. The trees are subdirectories of freeciv/code/installed. ~freeciv/games The base directory for running civservers; the cs wrapper script creates a subdirectory when it starts a civserver. We once lost a lot of data when the number of subdirectories grew to more than the Linux kernel could handle, but this was fixed with a kernel upgrade. No performance issues have been noticed, although something like an ls, due to the sorting it does, should obviously be avoided in scripts when possible. ~freeciv/* Some other directories exist under ~freeciv; the incidents directory contains reports and logs of individual incidents, mostly cases of obnoxious civserver user behavior. ~freeciv/htdocs/games The civserver reporting scripts take the data left by an ended game in ~freeciv/.freeciv/games and deposit their results under this directory. Most of the results are linked to from viewgame.phtml, the PHP script that displays an overview for an individual games; some are not; a few are password protected because they contain users' IP numbers.